//
//  EpubParseOperation.m
//  JSReader
//
//  Created by xzoscar on 16/6/23.
//  Copyright © 2016年 hujs. All rights reserved.
//

#import "EpubParseOperation.h"
#import "JSFileHandler.h"
#import "Book.h"
#import "SSZipArchive.h"
#import <UIKit/UIKit.h>
#import "TFHpple.h"

static NSString *const kColumnPageHTML = @"the first page of all htmls which contains the catalogs";

@interface EpubParseOperation ()<NSXMLParserDelegate>

@end

@implementation EpubParseOperation {
    NSString *_bookName;
    Book *_book;
    NSXMLParser *_parser;
    completion _block;
}

- (instancetype)init {
    
    NSAssert(NO, @"Invalid use of init; use initWithBookName to create EpubParseOperation");
    return [self init];
}

- (instancetype)initWithBookName:(NSString *)bookName completion:(completion)block {
    if ((self = [super init]) && bookName.length != 0) {
        _bookName = bookName;
        _book = [[Book alloc] init];
        _block = [block copy];
    }
    return self;
}

- (void)main {
    
    NSString *epubPath = [[JSFileHandler shared] allBookNameAndPath][_bookName];
    
    NSError *error;
    [SSZipArchive unzipFileAtPath:epubPath toDestination:kOneBookPath(_bookName) overwrite:NO password:nil error:&error];
    if (error) {
        DLog(@"%@", error);
        return;
    }
    
    [self parseContainer];
    [self parseContents];
}

- (void )parseContainer{
    
    //check whether root file path exists
    NSFileManager *filemanager=[NSFileManager defaultManager];
    NSString *strFilePath=[NSString stringWithFormat:@"%@/META-INF/container.xml",kOneBookPath(_bookName)];
    if ([filemanager fileExistsAtPath:strFilePath]) {
        
        //valid ePub
        DLog(@"Parse now");
        _parser = [[NSXMLParser alloc ] initWithContentsOfURL:[NSURL fileURLWithPath:strFilePath]];
        _parser.delegate = self;
        [_parser parse];
        
    }
    else {
    
        //Invalid ePub file
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error"
                                                      message:@"Root File not Valid"
                                                     delegate:self
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
        [alert show];
    }

}

- (void)parseContents {
    NSFileManager *filemanager=[NSFileManager defaultManager];
    NSString *strFilePath=[NSString stringWithFormat:@"%@/%@",kOneBookPath(_bookName), _book.rootPath];
    if ([filemanager fileExistsAtPath:strFilePath]) {
        _parser = nil;
        _parser = [[NSXMLParser alloc ] initWithContentsOfURL:[NSURL fileURLWithPath:strFilePath]];
        _parser.delegate = self;
        [_parser parse];
    } else {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error"
                                                      message:@"OPF File not found"
                                                     delegate:self
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
        [alert show];
    }

}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    
    NSLog(@"Error Occured : %@",[parseError description]);
    
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    
    if ([elementName isEqualToString:@"rootfile"]) {
                _book.rootPath = [attributeDict valueForKey:@"full-path"];
        
    }
    
    if ([elementName isEqualToString:@"package"]){
        
//        _epubContent=[[EpubContent alloc] init];
    }
    
    if ([elementName isEqualToString:@"manifest"]) {
        
        _book.manifest = [[NSMutableDictionary alloc] init];
    }
    
    if ([elementName isEqualToString:@"item"]) {
        
        [_book.manifest setValue:[attributeDict valueForKey:@"href"] forKey:[attributeDict valueForKey:@"id"]];
    }
    
    if ([elementName isEqualToString:@"spine"]) {
        
        _book.spine = [[NSMutableArray alloc] init];
    }
    
    if ([elementName isEqualToString:@"itemref"]) {
        
        [_book.spine addObject:[attributeDict valueForKey:@"idref"]];
    }

    if ([elementName isEqualToString:@"guide"]) {
        _book.guideDic = [NSMutableDictionary dictionary];
    }
    
    if ([elementName isEqualToString:@"reference"]) {
        [_book.guideDic setValue:[attributeDict valueForKey:@"href"] forKey:[attributeDict valueForKey:@"type"]];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    
    if ([elementName isEqualToString:@"manifest"]) {
        
//        DLog(@"%@", _book.manifest);
    }
    if ([elementName isEqualToString:@"spine"]) {
        
//        DLog(@"%@", _book.spine);
    }
    
    if ([elementName isEqualToString:@"package"]) {
        
        DLog(@"finish package!!!");
        [self parseChapterFromCoverHTMLPage];
    }
    
}

- (void)parseChapterFromCoverHTMLPage {
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *bookPath = kOneBookPath(_bookName);
    
    if ([manager fileExistsAtPath:bookPath]) {
        //content.opf中找到首页（guide）的文件名
        NSString *htmlName = htmlNameWithString(_book.guideDic[@"toc"]);
        //加载首页
        NSString *path = [NSString stringWithFormat:@"%@/%@",bookPath, htmlName];
        TFHpple *hpple = [[TFHpple alloc] initWithData:[NSData dataWithContentsOfFile:path] isXML:NO];
        //从首页中获取
        NSArray *array = [hpple searchWithXPathQuery:@"//body/p/a"];
      
        if (array.count != 0) {
            //不为0表示目录文件里有目录
            NSMutableDictionary *muDict = [NSMutableDictionary dictionary];
            NSMutableArray *muArr = [NSMutableArray array];
            for (TFHppleElement *oneElement in array) {
                [muArr addObject:oneElement.content];
                
                NSString *htmlName03 = htmlNameWithString(oneElement.attributes[@"href"]);
                [muDict setValue:htmlName03 forKey: oneElement.content];
            }
            _book.catalogs = [muArr copy];
            _book.chapterAndHTMLDict = [muDict copy];
            _book.name = _bookName;
        }

        if (_block) {
            _block(_book);
        }
    }
    
}

static inline NSString * htmlNameWithString(NSString *name) {
    NSString *str  = @"";
    if ([name rangeOfString:@"index"].length) {
        NSRange range = [name rangeOfString:@"#"];
        str = [name substringToIndex:range.location];
    }
    return str;
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    
}

@end
